package net.yeah.mickey_zhouyou.util.fcs.elem;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import javax.script.ScriptContext;

import net.yeah.mickey_zhouyou.util.ClassFieldsCache;
import net.yeah.mickey_zhouyou.util.fcs.ReaderOverException;
import net.yeah.mickey_zhouyou.util.fcs.ReaderWrapper;
import net.yeah.mickey_zhouyou.util.fcs.SyntaxException;
import net.yeah.mickey_zhouyou.util.fcs.serialize.IConvertor;

public class FieldSelector extends Selector {

	protected String fieldName;

	public static FieldSelector create(ReaderWrapper reader) throws IOException {
		char bs;
		try {
			bs = reader.readNotBlank();
		} catch (ReaderOverException e) {
			throw new SyntaxException("属性选择器必须以一个.开头", reader.getCurrentRow(),
					reader.getCurrentColumn());
		}
		if (bs != '.')
			throw new SyntaxException("属性选择器必须以一个.开头", reader.getCurrentRow(),
					reader.getCurrentColumn());
		FieldSelector res = new FieldSelector();
		try {
			res.fieldName = reader.readAString();
		} catch (ReaderOverException e) {
			res.fieldName = null;
		}
		if (res.fieldName == null || res.fieldName.length() == 0)
			throw new SyntaxException("属性选择器在.后面必须有一个属性名",
					reader.getCurrentRow(), reader.getCurrentColumn());
		return res;
	}

	@Override
	public Object select(Object obj, IConvertor objConvertor,
			ScriptContext context) {
		if (obj == null)
			return null;
		if (obj.getClass().isArray()) {
			int len = Array.getLength(obj);
			List<Object> res = new ArrayList<Object>(len);
			for (int i = 0; i < len; ++i) {
				Object o = ClassFieldsCache.getValue(Array.get(obj, i),
						this.fieldName);
				if (o != null)
					res.add(o);
			}
			return res;
		} else if (obj instanceof List) {
			List<?> list = (List<?>) obj;
			List<Object> res = new ArrayList<Object>(list.size());
			for (Object o : list) {
				Object o2 = ClassFieldsCache.getValue(o, this.fieldName);
				if (o2 != null)
					res.add(o2);
			}
			return res;
		}
		return ClassFieldsCache.getValue(obj, this.fieldName);
	}
}
